package tt.dz.util;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import tt.dz.entity.base.JsonCommon;

@Component
public class RedisClient
{

	private static Log log = LogFactory.getLog(RedisClient.class);

	private static JedisPool jedisPool;//非切片连接池

	
	private static String ip;
	@Value(value = "${redis.host}")
	public void setIp(String ip) {
		RedisClient.ip = ip;
	}

	private static int port;
	@Value(value = "${redis.port}")
	public void setPort(int port) {
		RedisClient.port = port;
	}
	
	private static int maxConn;
	@Value(value = "${redis.maxConn}")
	public void setMaxConn(int maxConn) {
		RedisClient.maxConn = maxConn;
	}	
	
	private static int maxIdle;
	@Value(value = "${redis.maxIdle}")
	public void setMaxIdle(int maxIdle) {
		RedisClient.maxIdle = maxIdle;
	}
	
	private static int minIdle;
	@Value(value = "${redis.minIdle}")
	public void setMinIdle(int minIdle) {
		RedisClient.minIdle = minIdle;
	}
	
	private static int timeout;
	@Value(value = "${redis.timeout}")
	public void setTimeout(int timeout) {
		RedisClient.timeout = timeout;
	}
	
	private static boolean testOnBorrow;
	@Value(value = "${redis.testOnBorrow}")
	public void setTestOnBorrow(boolean testOnBorrow) {
		RedisClient.testOnBorrow = testOnBorrow;
	}
	
	private static boolean testOnReturn;
	@Value(value = "${redis.testOnReturn}")
	public void setTestOnReturn(boolean testOnReturn) {
		RedisClient.testOnReturn = testOnReturn;
	}
	
	private static String passwd;
	@Value(value = "${redis.pass}")
	public void setPasswd(String passwd) {
		RedisClient.passwd = passwd;
	}
	
	@PostConstruct
	public void init()
	{
		try
		{
			JedisPoolConfig config = new JedisPoolConfig();
			// 控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
			// 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
			config.setMaxTotal(maxConn);

			// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
			config.setMaxIdle(maxIdle);
			config.setMinIdle(minIdle);
			// 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
			config.setMaxWaitMillis(timeout);
			// 在borrow一个jedis实例时,是否提前进行validate操作；如果为true,则得到的jedis实例均是可用的;
			// 当调用borrow Object方法时,是否进行有效性检查
			config.setTestOnBorrow(testOnBorrow);
			// 当调用Return Object方法时,是否进行有效性检查
			config.setTestOnReturn(testOnReturn);

			//Idle时进行连接扫描
			config.setTestWhileIdle(true);
			//表示idle object evitor两次扫描之间要sleep的毫秒数
			config.setTimeBetweenEvictionRunsMillis(30000);
			//表示idle object evitor每次扫描的最多的对象数
			config.setNumTestsPerEvictionRun(10);
			//表示一个对象至少停留在idle状态的最短时间，然后才能被idle object evitor扫描并驱逐；这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
			config.setMinEvictableIdleTimeMillis(60000);
			
			jedisPool = new JedisPool(config, ip, port, timeout, passwd);

			log.info("init redis success!");
		}
		catch (Exception e)
		{
			log.error("init redis fail!", e);
			throw e;
		}
	}

	@Deprecated
	public static void putByte(byte[] key, byte[] value)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.set(key, value);
		releaseConnect(jedis);
	}

	@Deprecated
	public static byte[] getByte(byte[] key)
	{
		Jedis jedis = RedisClient.getConnect();
		byte[] result = jedis.get(key);
		releaseConnect(jedis);
		return result;
	}

	@Deprecated
	public static void putString(String key, String value)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.set(key, value);
		releaseConnect(jedis);
	}

	@Deprecated
	public static void putList(String key, List<String> list)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.lpush(key, list.toArray(new String[list.size()]));
		releaseConnect(jedis);
	}

	@Deprecated
	//map 里面的key 对应的value 不能为空值
	public static void putMap(String key, Map<String, String> map)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.hmset(key, map);
		releaseConnect(jedis);
	}
	
	
	public static void putMapValue(String key, Map<String, String> map)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.hmset(key, map);
		releaseConnect(jedis);
	}

	@Deprecated
	public static void delByKey(String key)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.del(key);
		releaseConnect(jedis);
	}

	@Deprecated
	public static void expire(String key, int seconds)
	{
		Jedis jedis = RedisClient.getConnect();
		jedis.expire(key, seconds);//按秒计算
		releaseConnect(jedis);
	}

	@Deprecated
	public static String get(String key)
	{
		Jedis jedis = RedisClient.getConnect();
		String result = jedis.get(key);
		releaseConnect(jedis);
		return result;
	}

	@Deprecated
	public static Map<String, String> getMap(String key)
	{
		Jedis jedis = RedisClient.getConnect();
		Map<String, String> result = jedis.hgetAll(key);
		releaseConnect(jedis);
		return result;
	}

	@Deprecated
	public static List<String> getList(String key)
	{
		Jedis jedis = RedisClient.getConnect();
		List<String> result = jedis.lrange(key, 0, -1);
		releaseConnect(jedis);
		return result;
	}

	
	/**
	 * 获取对象池对象
	 *
	 * @return
	 * @throws Exception
	 */
	public static Jedis getConnect()
	{
		try
		{
			if (jedisPool == null)
				return null;

			return jedisPool.getResource();
		}
		catch (Exception e)
		{
			log.error("Get jedis connect fail!" + e);
			jedisPoolReset();
			try
			{
				if (jedisPool == null)
					return null;
				return jedisPool.getResource();
			}
			catch (Exception ex)
			{
			    throw ex;
			}
		}
	}

	/**
	 * 释放对象池对象
	 *
	 * @param connnect
	 */
	@Deprecated
	public static void releaseConnect(Jedis connnect)
	{
		jedisPool.returnResource(connnect);
	}
	
	/**
	* jedis连接池重置
	*/
	public static void jedisPoolReset() {
	    //JedisPool jedisPool = JedisUtil.getJedisPool();
		try {
			jedisPool.destroy();
		} catch (Exception e) {
		}
		try
		{
			JedisPoolConfig config = new JedisPoolConfig();
			// 控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
			// 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
			config.setMaxTotal(maxConn);

			// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
			config.setMaxIdle(maxIdle);
			config.setMinIdle(minIdle);
			// 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
			config.setMaxWaitMillis(timeout);
			// 在borrow一个jedis实例时,是否提前进行validate操作；如果为true,则得到的jedis实例均是可用的;
			// 当调用borrow Object方法时,是否进行有效性检查
			config.setTestOnBorrow(testOnBorrow);
			// 当调用Return Object方法时,是否进行有效性检查
			config.setTestOnReturn(testOnReturn);

			//Idle时进行连接扫描
			config.setTestWhileIdle(true);
			//表示idle object evitor两次扫描之间要sleep的毫秒数
			config.setTimeBetweenEvictionRunsMillis(30000);
			//表示idle object evitor每次扫描的最多的对象数
			config.setNumTestsPerEvictionRun(10);
			//表示一个对象至少停留在idle状态的最短时间，然后才能被idle object evitor扫描并驱逐；这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
			config.setMinEvictableIdleTimeMillis(60000);
			
			jedisPool = new JedisPool(config, ip, port, timeout, passwd);

			log.info("reinit redis success!");
		}
		catch (Exception e)
		{
			log.error("reinit redis fail!", e);
			throw e;
		}
	}
	
//	public static byte[] getBytefromRedis(String key) {
//		//redis中查询
//		Jedis jedis = RedisClient.getConnect();
//		byte[] value_byte = jedis.get(key.getBytes());
//		jedis.close();
//		return value_byte;
//	}
	
	public static <T> T getBytefromRedis(String key) {
		JsonCommon json = new JsonCommon();
		//redis中查询
		Jedis jedis = RedisClient.getConnect();
		byte[] valueByte = jedis.get(key.getBytes());
		jedis.close();
		if(valueByte!=null){
			 T value =   (T) SerializeUtil.unserialize(valueByte);
			 return value;
		}
		return null;
	}
	

}